package com.mocchira.music.radio;

import java.io.File;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class RankingActivity extends Activity {

    public enum RESION {
        am, // America
        ar, // Asia and Russia
        eu, // Europe
        ot  // others
    }
    ListView rankingList;
    RankingLoader loader;
    
    private static Map<String, Bitmap> imageCache = new HashMap<String, Bitmap>(100);
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ranking);
        rankingList = (ListView)findViewById(R.id.rankingListView);
        rankingList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                Intent intent = new Intent(RankingActivity.this, FMRPlayActivity.class);
                Bundle bundle = new Bundle();
                String artist = ((TextView)((LinearLayout)view).findViewById(R.id.artistText)).getText().toString();
                bundle.putString(R.string.bundle_artist+"", artist);
                intent.putExtras(bundle);
                startActivity(intent);
            }
        });
        Bundle bundle = getIntent().getExtras();
        String region = (String)bundle.get(R.string.bundle_ranking + "");
        loader = new RankingLoader(this, region);

    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (loader != null)
            loader.onDestroy();
        RankingListAdapter adapter = (RankingListAdapter) rankingList.getAdapter();
        if (adapter != null)
            adapter.onDestroy();
    }

    private class RankingListAdapter implements ListAdapter, IDownloadListener {
        private List<List<String>> ranking = null;
        private Context ctx;
        private LayoutInflater inflater;
        private DownloadManager dlmanager;
        private Map<String, Integer> url2viewIndex = null;
        private View[] viewCache = null;
        
        public RankingListAdapter(Context ctx, File file) throws Exception {
            this.ctx = ctx;
            ranking = FileUtil.readCSV(file, '\t');
            url2viewIndex = new HashMap<String, Integer>(ranking.size());
            viewCache = new View[ranking.size()];
            for(@SuppressWarnings("unused") View view: viewCache)
                view = null;
            inflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            dlmanager = new DownloadManager(ctx, this);
        }

        @Override
        public int getCount() {
            return ranking == null ? 0 : ranking.size();
        }

        @Override
        public Object getItem(int position) {
            return ranking == null ? null : ranking.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (viewCache[position] != null)
                return viewCache[position];
            
            LinearLayout view = (LinearLayout) inflater.inflate(R.layout.ranking_col, null);
            TextView text = (TextView)view.findViewById(R.id.artistText);
            ImageView image = (ImageView)view.findViewById(R.id.artistImange);
            List<String> rec = ranking.get(position);
            if (rec == null || rec.size() == 0) {
                text.setText("");
                image.setImageDrawable(ctx.getResources().getDrawable(R.drawable.loading));
            } else {
                // text
                try {
                    text.setText(URLDecoder.decode(rec.get(0),"UTF-8"));
                }catch(Exception ex) {};
                // image
                String imgurl;
                if (rec.size() == 1 || (imgurl = rec.get(1)).length() == 0) {
                    image.setImageDrawable(ctx.getResources().getDrawable(R.drawable.loading));
                } else {
                    Bitmap bitmap = imageCache.get(imgurl);
                    if (bitmap == null) {
                        if (url2viewIndex.get(imgurl) == null) {
                            image.setImageDrawable(ctx.getResources().getDrawable(R.drawable.loading));
                            dlmanager.enqueue(imgurl);
                            url2viewIndex.put(imgurl, position);
                        }
                    } else {
                        image.setImageBitmap(bitmap);
                    }
                }
            }
            viewCache[position] = view;
            return view;
        }
        @Override
        public void registerDataSetObserver(DataSetObserver observer) {
            // TODO Auto-generated method stub
            
        }
        @Override
        public void unregisterDataSetObserver(DataSetObserver observer) {
            // TODO Auto-generated method stub
            
        }
        @Override
        public boolean hasStableIds() {
            return true;
        }
        @Override
        public int getItemViewType(int position) {
            return 0;
        }
        @Override
        public int getViewTypeCount() {
            return 1;
        }
        @Override
        public boolean isEmpty() {
            return ranking == null ? true : ranking.size() == 0;
        }
        @Override
        public boolean areAllItemsEnabled() {
            return false;
        }
        @Override
        public boolean isEnabled(int position) {
            return true;
        }

        @Override
        public void onComplete(String url, File tmpFile, Exception ex) {
            if (ex != null) return;
            Bitmap bm = BitmapFactory.decodeFile(tmpFile.getAbsolutePath());
            tmpFile.delete();
            imageCache.put(url, bm);
            int pos = url2viewIndex.get(url);
            LinearLayout cache = (LinearLayout) viewCache[pos];
            ((ImageView)cache.findViewById(R.id.artistImange)).setImageBitmap(bm);
        }
        
        public void onDestroy() {
            ctx = null;
            for (List<String> rec: ranking) {
                rec.clear();
                rec = null;
            }
            if (ranking != null)
                ranking.clear();
            ranking = null;
            if (imageCache != null) {
                for (String key :imageCache.keySet()) {
                    Bitmap bm = imageCache.get(key);
                    if (bm != null)
                        bm.recycle();
                    bm = null;
                }
                imageCache.clear();
            }
            if (url2viewIndex != null)
                url2viewIndex.clear();
            url2viewIndex = null;
            if (viewCache != null)
                for (@SuppressWarnings("unused") View view: viewCache) {
                    view = null;
                }
            viewCache = null;
            System.gc();
        }
    }

    private class RankingLoader implements IDownloadListener {
        
        private static final String RANKING_URL = "http://shopping.mocchira.com/ranking.csv";
        private static final long RANKING_EXPIRE = 3600 * 12 * 1000;

        private DownloadManager dlmanager = null;
        private File rankingFile;
        private Context ctx;

        private RankingLoader(Context ctx, String regionCode) {
            this.ctx = ctx;
            rankingFile = new File(ctx.getFilesDir(), regionCode + "__ranking__.json");
            if (isExpire(rankingFile)) {
                dlmanager = new DownloadManager(ctx, this);
                dlmanager.enqueue(RANKING_URL + "." + regionCode);
            } else {
                RankingListAdapter adapter = null;
                try {
                    adapter = new RankingListAdapter(ctx, rankingFile);
                } catch (Exception nex) {
                    Toast.makeText(ctx, R.string.msg_network_err, Toast.LENGTH_LONG).show();
                    return;
                }
                if (adapter != null)
                    rankingList.setAdapter(adapter);
            }
        }
        private boolean isExpire(File file) {
            if (file == null || !file.canRead())
                return true;
            long lastMod = file.lastModified();
            return ((System.currentTimeMillis() - lastMod) > RANKING_EXPIRE);
        }
        @Override
        public void onComplete(String url, File tmpFile, Exception ex) {
            if (ex != null) {
                Toast.makeText(ctx, R.string.msg_network_err, Toast.LENGTH_LONG).show();
            } else {
                tmpFile.renameTo(rankingFile);
                RankingListAdapter adapter = null;
                try {
                    adapter = new RankingListAdapter(ctx, rankingFile);
                } catch (Exception nex) {
                    Toast.makeText(ctx, R.string.msg_network_err, Toast.LENGTH_LONG).show();
                    return;
                }
                if (adapter != null)
                    rankingList.setAdapter(adapter);
            }
        }
        
        public void onDestroy() {
            ctx = null;
        }
    }
}
